package com.abou.manager.exception;

import java.io.Serializable;
import org.apache.commons.lang.StringUtils;
import com.abou.utils.common.BeanUtils;

/**
 * Base class for all exceptions raised by the manager layer.
 */
public class ManagerException extends RuntimeException implements Serializable {
  
  /**
   * Serial version uid for the class
   */
  private static final long serialVersionUID = 1L;
  
  /**
   * The separator between the params in the params string representation
   */
  public static final String PARAMS_SEP = ",";
  
  private EManagerErrorCode code;
  private Object[] params = new Object[0];
  
  /**
   * The constructor with a code.
   * 
   * @param code See {@link #getCode()}.
   */
  public ManagerException(EManagerErrorCode code) {

    super("", null);
    this.code = code;
  }
  
  /**
   * The constructor with a code.
   * 
   * @param code See {@link #getCode()}.
   * @param params See {@link #getParams()}.
   * @param wrappedEx The exception that triggered this exception.
   */
  public ManagerException(EManagerErrorCode code, Object[] params,
      Throwable wrappedEx) {

    super("", wrappedEx);
    this.code = code;
    
    if (params != null) {
      
      this.params = BeanUtils.clone(params);
      
    } else if (wrappedEx != null) {
      
      if (StringUtils.isBlank(wrappedEx.getMessage())) {
        
        this.params = new String[] { wrappedEx.getClass().getSimpleName() };
        
      } else {
        
        this.params = new String[] { wrappedEx.getMessage() };
      }
    }
  }
  
  /**
   * The constructor with a code and a message.
   * 
   * @param code See {@link #getCode()}.
   * @param msg The message for the exception.
   */
  public ManagerException(EManagerErrorCode code, String msg) {

    super(msg, null);
    this.code = code;
  }
  
  /**
   * The constructor with a message and the caught exception.
   * 
   * @param code See {@link #getCode()}.
   * @param msg The message for the exception.
   * @param wrappedEx The exception that triggered this exception.
   */
  public ManagerException(EManagerErrorCode code, String msg,
      Throwable wrappedEx) {

    super(msg, wrappedEx);
    this.code = code;
  }
  
  /**
   * @return The error code
   */
  public EManagerErrorCode getCode() {

    return code;
  }
  
  /**
   * @return The parameters for the displayable exception message
   */
  public Object[] getParams() {

    return params;
  }
  
  /**
   * @return The string representation of the parameters
   */
  public String getParamsAsString() {

    StringBuffer buffer = new StringBuffer();
    
    if (params != null) {
      
      for (Object obj : params) {
        
        buffer.append(obj);
        buffer.append(PARAMS_SEP);
      }
    }
    
    return buffer.toString();
  }
  
  @Override
  public String toString() {

    return super.toString() + "\nCode : " + getCode();
  }
}
